package com.flyqiu.form.spring.boot.starter;

import com.flyqiu.form.api.config.IFlyQiuFormConfig;
import com.flyqiu.form.api.event.FlyQiuTableDataEvent;
import com.flyqiu.form.api.event.FlyQiuTableEvent;
import com.flyqiu.form.api.rule.FlyQiuFormDataRule;
import com.flyqiu.form.api.spi.FlyQiuFormStoreInitialization;
import lombok.Getter;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.ApplicationContext;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * SpringFlyQiuFormConfig 配置类，用于初始化和获取表单相关的规则、事件和存储初始化对象
 */
@Getter
public class SpringFlyQiuFormConfig implements IFlyQiuFormConfig {

    // 表单数据规则列表
    private List<FlyQiuFormDataRule> flyQiuFormDataRules = new ArrayList<>();
    // 表格事件列表
    private List<FlyQiuTableEvent> flyQiuTableEvents = new ArrayList<>();
    // 表格数据事件列表
    private List<FlyQiuTableDataEvent> flyQiuTableDataEvents = new ArrayList<>();
    // 表单存储初始化列表
    private List<FlyQiuFormStoreInitialization> flyQiuFormStoreInitializations = new ArrayList<>();

    // 应用上下文，用于获取Bean实例
    private final ApplicationContext applicationContext;

    /**
     * 构造函数，初始化配置类
     *
     * @param context 应用上下文
     */
    public SpringFlyQiuFormConfig(ApplicationContext context) {
        this.applicationContext = context;
        init();
    }

    /**
     * 初始化方法，获取并设置各类事件和规则的Bean实例
     */
    private void init() {
        flyQiuTableEvents = getBeanInstances(FlyQiuTableEvent.class);
        flyQiuTableDataEvents = getBeanInstances(FlyQiuTableDataEvent.class);
        flyQiuFormDataRules = getBeanInstances(FlyQiuFormDataRule.class);
        flyQiuFormStoreInitializations = getBeanInstances(FlyQiuFormStoreInitialization.class);
    }

    /**
     * 获取单个Bean实例
     *
     * @param clazz Bean的类类型
     * @param <T>   泛型标记
     * @return Bean实例
     */
    private <T> T getBeanInstance(Class<T> clazz) {
        ObjectProvider<T> beanProvider = applicationContext.getBeanProvider(clazz);
        return beanProvider.getIfAvailable();
    }

    /**
     * 获取多个Bean实例列表
     *
     * @param clazz Bean的类类型
     * @param <T>   泛型标记
     * @return Bean实例列表
     */
    private <T> List<T> getBeanInstances(Class<T> clazz) {
        ObjectProvider<T> beanProvider = applicationContext.getBeanProvider(clazz);
        Iterator<T> iterator = beanProvider.iterator();
        List<T> result = new ArrayList<>();
        while (iterator.hasNext()) {
            result.add(iterator.next());
        }
        return result;
    }

}
